package org.ix.gateway.route.service.impl;

import org.ix.common.exception.DmpDataNotFoundException;
import org.ix.common.models.PageList;
import org.ix.common.utils.ObjectUtils;
import org.ix.gateway.route.model.request.GatewayRouteAddRequest;
import org.ix.gateway.route.model.request.GatewayRoutePatchRequest;
import org.ix.gateway.route.model.request.GatewayRouteQueryRequest;
import org.ix.gateway.route.model.request.GatewayRouteSaveRequest;
import org.ix.gateway.route.model.response.GatewayRouteDetailResponse;
import org.ix.gateway.route.model.response.GatewayRouteListItemResponse;
import org.ix.gateway.route.service.GatewayRouteService;
import org.ix.gateway.route.constant.DeletedConstant;
import org.ix.gateway.route.presentation.condition.GatewayRouteSelectCondition;
import org.ix.gateway.route.presentation.condition.GatewayRouteUpdateCondition;
import org.ix.gateway.route.presentation.entity.GatewayRouteEntity;
import org.ix.gateway.route.presentation.entity.GatewayRouteEntityExt;
import org.ix.gateway.route.presentation.mapper.GatewayRouteMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;

/**
 * 网关路由业务逻辑
 *
 * @author 郗世豪（rarexixi@sina.com）
 */
@Service("gatewayRouteService")
@Transactional
public class GatewayRouteServiceImpl implements GatewayRouteService {

    final GatewayRouteMapper gatewayRouteMapper;

    @Autowired
    public GatewayRouteServiceImpl(GatewayRouteMapper gatewayRouteMapper) {
        this.gatewayRouteMapper = gatewayRouteMapper;
    }

    /**
     * 添加网关路由
     *
     * @param addRequest 网关路由
     * @return 受影响的行数
     * @author 郗世豪（rarexixi@sina.com）
     */
    @Override
    public GatewayRouteDetailResponse add(GatewayRouteAddRequest addRequest) {
        GatewayRouteEntity entity = ObjectUtils.copy(addRequest, GatewayRouteEntity.class);
        gatewayRouteMapper.insert(entity);
        return getById(entity.getId());
    }

    /**
     * 批量添加网关路由
     *
     * @param list 网关路由列表
     * @return 受影响的行数
     * @author 郗世豪（rarexixi@sina.com）
     */
    @Override
    public int batchAdd(Collection<GatewayRouteAddRequest> list) {
        List<GatewayRouteEntity> entityList = ObjectUtils.copy(list, GatewayRouteEntity.class);
        return gatewayRouteMapper.batchInsert(entityList);
    }

    /**
     * 删除网关路由
     *
     * @param patchRequest 更新条件请求
     * @return 受影响的行数
     * @author 郗世豪（rarexixi@sina.com）
     */
    @Override
    public int delete(GatewayRoutePatchRequest patchRequest) {
        GatewayRouteUpdateCondition condition = ObjectUtils.copy(patchRequest, GatewayRouteUpdateCondition.class);
        return gatewayRouteMapper.delete(condition);
    }

    /**
     * 禁用网关路由
     *
     * @param patchRequest 更新条件请求
     * @return 受影响的行数
     * @author 郗世豪（rarexixi@sina.com）
     */
    @Override
    public int disable(GatewayRoutePatchRequest patchRequest) {
        GatewayRouteUpdateCondition condition = ObjectUtils.copy(patchRequest, GatewayRouteUpdateCondition.class);
        GatewayRouteEntity entity = ObjectUtils.copy(patchRequest, GatewayRouteEntity.class, "id");
        entity.setDeleted(DeletedConstant.INVALID);
        return gatewayRouteMapper.update(entity, condition);
    }

    /**
     * 启用网关路由
     *
     * @param patchRequest 更新条件请求
     * @return 受影响的行数
     * @author 郗世豪（rarexixi@sina.com）
     */
    @Override
    public int enable(GatewayRoutePatchRequest patchRequest) {
        GatewayRouteUpdateCondition condition = ObjectUtils.copy(patchRequest, GatewayRouteUpdateCondition.class);
        GatewayRouteEntity entity = ObjectUtils.copy(patchRequest, GatewayRouteEntity.class, "id");
        entity.setDeleted(DeletedConstant.VALID);
        return gatewayRouteMapper.update(entity, condition);
    }

    /**
     * 根据路由id更新网关路由
     *
     * @param saveRequest 保存网关路由请求实体
     * @param id 路由id
     * @return 更新后的网关路由详情
     * @author 郗世豪（rarexixi@sina.com）
     */
    @Override
    public GatewayRouteDetailResponse updateById(GatewayRouteSaveRequest saveRequest, String id) {
        GatewayRouteUpdateCondition condition = new GatewayRouteUpdateCondition();
        condition.setId(id);
        GatewayRouteEntity entity = ObjectUtils.copy(saveRequest, GatewayRouteEntity.class);
        gatewayRouteMapper.update(entity, condition);
        GatewayRouteDetailResponse result;
        if (saveRequest.getId() == null) {
            result = getById(id);
        } else {
            result = getById(saveRequest.getId());
        }
        return result;
    }

    /**
     * 根据路由id获取网关路由详情
     *
     * @param id 路由id
     * @return 网关路由详情
     * @author 郗世豪（rarexixi@sina.com）
     */
    @Override
    @Transactional(readOnly = true)
    public GatewayRouteDetailResponse getById(String id) {
        GatewayRouteEntityExt entity = gatewayRouteMapper.detail(id);
        if (entity == null) {
            throw new DmpDataNotFoundException("网关路由不存在");
        }
        return ObjectUtils.copy(entity, GatewayRouteDetailResponse.class);
    }

    /**
     * 获取网关路由列表
     *
     * @param queryRequest 搜索条件
     * @return 符合条件的网关路由列表
     */
    @Override
    @Transactional(readOnly = true)
    public List<GatewayRouteListItemResponse> getList(GatewayRouteQueryRequest queryRequest) {
        GatewayRouteSelectCondition condition = ObjectUtils.copy(queryRequest, GatewayRouteSelectCondition.class);
        List<GatewayRouteEntityExt> list = gatewayRouteMapper.select(condition);
        return ObjectUtils.copy(list, GatewayRouteListItemResponse.class);
    }

    /**
     * 分页获取网关路由列表
     *
     * @param queryRequest 搜索条件
     * @param pageNum      页码
     * @param pageSize     分页大小
     * @return 符合条件的网关路由分页列表
     */
    @Override
    @Transactional(readOnly = true)
    public PageList<GatewayRouteListItemResponse> getPageList(GatewayRouteQueryRequest queryRequest, Integer pageNum, Integer pageSize) {

        GatewayRouteSelectCondition condition = ObjectUtils.copy(queryRequest, GatewayRouteSelectCondition.class);
        PageInfo<GatewayRouteEntityExt> pageInfo = PageHelper.startPage(pageNum, pageSize).doSelectPageInfo(() -> gatewayRouteMapper.select(condition));

        List<GatewayRouteListItemResponse> list = ObjectUtils.copy(pageInfo.getList(), GatewayRouteListItemResponse.class);
        return new PageList<>(pageInfo.getPageNum(), pageInfo.getPageSize(), pageInfo.getTotal(), list);
    }
}
